perm filename C4[CLS,LSP] blob sn#871198 filedate 1989-03-17 generic text, type C, neo UTF8
COMMENT āŠ—   VALID 00002 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	%Start Part 4 of 6 concep.tex
C00038 ENDMK
CāŠ—;
%Start Part 4 of 6 concep.tex
In general, the effective method is some combination of the applicable
methods.  It is defined by a Lisp form that contains calls to some or all
of the applicable methods, returns the value or values that will be
returned as the value or values of the generic function, and optionally
makes some of the methods accessible by means of {\bf call-next-method}.
This Lisp form is the body of the effective method; it is augmented with
an appropriate lambda-list to make it a function.

The role of each method in the effective method is determined by its
method qualifiers and the specificity of the method.  A qualifier
serves to mark a method, and the meaning of a qualifier is
determined by the way that these marks are used by this step
of the procedure.  If an applicable method has an unrecognized
qualifier, this step signals an error and does not include that method
in the effective method.

When standard method combination is used together with qualified methods, 
the effective method is produced as described in the section
``Standard Method Combination.''

Another type of method combination can be specified by using the {\bf
:method-combination} option of {\bf defgeneric} or of any of the other
forms that specify generic function options.  In this way this step of
the procedure can be customized.

New types of method combination can be defined by using the 
{\bf define-method-combination} macro. 

\goodbreak

The meta-object level also offers a mechanism for defining new types
of method combination.  The generic function {\bf
compute-effective-method} receives as arguments the generic function,
the method combination object, and the sorted list of applicable
methods.  It returns the Lisp form that defines the effective method.
A method for {\bf compute-effective-method} can be defined directly by
using {\bf defmethod} or indirectly by using {\bf
define-method-combination}.  A {\bit method combination object} is an
object that encapsulates the method combination type and options
specified by the {\bf :method-combination} option to forms that
specify generic function options.

\endsubsubsection

\newpage

\beginImplNote
In the simplest implementation, the generic function would compute
the effective method each time it was called.  In practice, this will
be too inefficient for some implementations.  Instead, these
implementations might employ a variety of optimizations of the
three-step procedure. Some illustrative examples of such optimizations
are the following:

\beginlist

\item{\bull} Use a hash table keyed by the class of the arguments to
store the effective method.

\item{\bull} Compile the effective method and save the resulting
compiled function in a table.

\item{\bull} Recognize the Lisp form as an instance of a pattern of
control structure and substitute a closure that implements
that structure.

\item{\bull} Examine the parameter specializers of all methods for the
generic function and enumerate all possible effective methods.
Combine the effective methods, together with code to select from
among them, into a single function and compile that function.  Call
that function whenever the generic function is called.
\endlist
\endImplNote


\endsubSection%{Determining the Effective Method}

\beginsubSection{Standard Method Combination}

Standard method combination is supported by the class {\bf
standard-generic-function}. It is used if no other type of method
combination is specified or if the built-in method combination type
{\bf standard} is specified. 

{\bit Primary methods\/} define the main action of the effective method,  
while {\bit auxiliary methods\/} modify that action in one of three ways.
A primary method has no method qualifiers.

An auxiliary method is a method whose method qualifier is {\bf
:before}, {\bf :after}, or {\bf :around}.  Standard method combination
allows no more than one qualifier per method; if a method definition
specifies more than one qualifier per method, an error is signaled.

\beginlist

\item{\bull}
A {\bf :before} method has the keyword {\bf :before} as its
only qualifier.  A {\bf :before} method specifies code that is to be
run before any primary methods.

\item{\bull}
An {\bf :after} method has the keyword {\bf :after} as its only
qualifier.  An {\bf :after} method specifies code that is to be run
after primary methods.  

\item{\bull}
An {\bf :around} method has the keyword {\bf :around} as its only
qualifier. An {\bf :around} method specifies code that is to
be run instead of other applicable methods but which is
able to cause some of them to be run.

\endlist

\newpage

The semantics of standard method combination is as follows:

\beginlist

\item{\bull} If there are any {\bf :around} methods, the most specific
{\bf :around} method is called.  It supplies the value or values of the
generic function.

\item{\bull} Inside the body of an {\bf :around} method, {\bf
call-next-method} can be used to call the next method.  When the next
method returns, the {\bf :around} method can execute more code,
perhaps based on the returned value or values.  The generic function
{\bf no-next-method} is invoked if {\bf call-next-method} is used and
there is no applicable method to call.  The function {\bf
next-method-p} may be used to determine whether a next method exists.

\item{\bull} 
If an {\bf :around} method invokes {\bf call-next-method}, the next
most specific {\bf :around} method is called, if one is applicable.
If there are no {\bf :around} methods or if {\bf
call-next-method} is called by the least specific {\bf :around}
method, the other methods are called as follows:

\itemitem{--} All the {\bf :before} methods are called, in
most-specific-first order.  Their values are ignored.
An error is signaled if {\bf call-next-method} is used in a
{\bf :before} method.

\itemitem{--} The most specific primary method is called.  Inside the
body of a primary method, {\bf call-next-method} may be used to call
the next most specific primary method.  When that method returns, the
previous primary method can execute more code, perhaps based on the
returned value or values.  The generic function {\bf no-next-method}
is invoked if {\bf call-next-method} is used and there are no more
applicable primary methods.  The function {\bf next-method-p} may be
used to determine whether a next method exists.  If {\bf
call-next-method} is not used, only the most specific primary method
is called.


\itemitem{--} All the {\bf :after} methods are called in
most-specific-last order.  Their values are ignored.
An error is signaled if {\bf call-next-method} is used in an
{\bf :after} method.

\item{\bull} If no {\bf :around} methods were invoked, the most
specific primary method supplies the value or values returned by the
generic function.  The value or values returned by the invocation of
{\bf call-next-method} in the least specific {\bf :around} method are
those returned by the most specific primary method.

\endlist

In standard method combination, if there is an applicable method
but no applicable primary method, an error is signaled.

The {\bf :before} methods are run in most-specific-first order while
the {\bf :after} methods are run in least-specific-first order.  The
design rationale for this difference can be illustrated with an
example.  Suppose class $C \sub 1$ modifies the behavior of its
superclass, $C \sub 2$, by adding {\bf :before} and {\bf :after}
methods. Whether the behavior of the class $C\sub 2$ is defined
directly by methods on $C\sub 2$ or is inherited from its superclasses
does not affect the relative order of invocation of methods on
instances of the class $C\sub 1$.  Class $C \sub 1$'s {\bf :before}
method runs before all of class $C \sub 2$'s methods.  Class $C \sub
1$'s {\bf :after} method runs after all of class $C \sub 2$'s methods.

By contrast, all {\bf :around} methods run before any other methods
run.  Thus a less specific {\bf :around} method runs before a more
specific primary method.

If only primary methods are used and if {\bf call-next-method} is not
used, only the most specific method is invoked; that is, more specific
methods shadow more general ones. 

\endsubSection%{Standard Method Combination}

\beginsubSection{Declarative Method Combination}

The macro {\bf define-method-combination} defines new forms of method
combination.  It provides a mechanism for customizing the production
of the effective method. The default procedure for producing an
effective method is described in the section ``Determining the
Effective Method.''  There are two forms of {\bf
define-method-combination}.  The short form is a simple facility while
the long form is more powerful and more verbose.  The long form
resembles {\bf defmacro} in that the body is an expression that
computes a Lisp form; it provides mechanisms for implementing
arbitrary control structures within method combination and for
arbitrary processing of method qualifiers.  The syntax and use of both
forms of {\bf define-method-combination} are explained in Chapter~2.

\endsubSection%{Declarative Method Combination}

\goodbreak

\beginsubSection{Built-in Method Combination Types}

The \CLOS\ provides a set of built-in method combination types.  To
specify that a generic function is to use one of these method
combination types, the name of the method combination type is given as
the argument to the {\bf :method-combination} option to {\bf
defgeneric} or to the {\bf :method-combination} option to any of the
other forms that specify generic function options.

The names of the built-in  method combination types are
{\bf +}, {\bf and}, {\bf append}, {\bf list}, {\bf max}, {\bf min}, 
{\bf nconc}, {\bf or}, {\bf progn}, and {\bf standard}.

The semantics of the {\bf standard} built-in method combination type was
described in the section ``Standard Method Combination.''  The other
built-in method combination types are called {\bit simple built-in method
combination types.}

The simple built-in method combination types act as though they were
defined by the short form of {\bf define-method-combination}.  They
recognize two roles for methods:

\beginlist

\item{\bull} An {\bf :around} method has the keyword symbol {\bf
:around} as its sole qualifier.  The meaning of {\bf :around}
methods is the same as in standard method combination.  Use of the
functions {\bf call-next-method} and {\bf next-method-p} is supported
in {\bf :around} methods.

\item{\bull} A primary method has the name of the method combination
type as its sole qualifier.  For example, the built-in method
combination type {\bf and} recognizes methods whose sole qualifier is
{\bf and}; these are primary methods. Use of the functions {\bf
call-next-method} and {\bf next-method-p} is not supported in primary
methods.

\endlist

The semantics of the simple built-in method combination types is as
follows:

\beginlist
\item{\bull}
If there are any {\bf :around} methods, the most specific {\bf :around}
method is called.   It supplies the value or values of the generic function. 

\item{\bull} Inside the body of an {\bf :around} method, the function
{\bf call-next-method} can be used to call the next method.  The
generic function {\bf no-next-method} is invoked if {\bf
call-next-method} is used and there is no applicable method to call.
The function {\bf next-method-p} may be used to determine whether a
next method exists. When the next method returns, the {\bf :around}
method can execute more code, perhaps based on the returned value or
values.

\item{\bull} If an {\bf :around} method invokes {\bf
call-next-method}, the next most specific {\bf :around} method is
called, if one is applicable.  If there are no {\bf :around} methods
or if {\bf call-next-method} is called by the least specific {\bf
:around} method, a Lisp form derived from the name of the built-in
method combination type and from the list of applicable primary
methods is evaluated to produce the value of the generic function.
Suppose the name of the method combination type is {\it operator\/}
and the call to the generic function is of the form

$$(\hbox{{\it generic-function}}\ a\sub 1\ldots a\sub n)$$

\item{} Let $M\sub 1,\ldots,M\sub k$ be the applicable primary methods
in order; then the derived Lisp form is

$$(\hbox{{\it operator}}\ \langle M\sub  1%
\ a\sub 1\ldots a\sub n\rangle\ldots\langle%
M\sub k\ a\sub 1\ldots a\sub n\rangle)$$

\item{} If the expression $\langle M\sub i \ a\sub 1\ldots a\sub
n\rangle$ is
evaluated, the method $M\sub i$ will be applied to the arguments
$a\sub 1\ldots a\sub n$.  
For example,
if {\it operator\/} is {\bf or},
the expression $\langle M\sub i \ a\sub 1\ldots a\sub n\rangle$ is
evaluated only if $\langle M\sub j \ a\sub 1\ldots a\sub n\rangle$,
$1\leq j<i$, returned {\bf nil}.

\item{} The default order for the primary methods is {\bf
:most-specific-first}.  However, the order can be reversed by supplying
{\bf :most-specific-last} as the second argument to the {\bf
:method-combination} option.  \endlist

\goodbreak

The simple built-in method combination types require exactly one qualifier per
method.  An error is signaled if there are applicable methods with no
qualifiers or with qualifiers that are not supported by the method
combination type. An error is signaled if there are applicable {\bf :around}
methods and no applicable primary methods.

\endsubSection%{Built-in Method Combination Types}

\endSection%{Method Selection and Combination}

\beginSection{Meta-Objects}

The implementation of the \OS\ manipulates classes, methods, and generic
functions.  The meta-object protocol specifies a set of generic
functions defined by methods on classes; the behavior of those generic
functions defines the behavior of the \OS.  The instances of the classes
on which those methods are defined are called {\bit meta-objects}.  Programming
at the meta-object protocol level involves defining new classes of
meta-objects along with methods specialized on these classes.

\beginsubSection{Metaclasses}

The {\bit metaclass\/} of an object is the class of its class.  The
metaclass determines the representation of instances of its instances and
the forms of inheritance used by its instances for slot descriptions and
method inheritance.  The metaclass mechanism can be used to provide
particular forms of optimization or to tailor the \CLOS\ for particular
uses.  The protocol for defining metaclasses is discussed in the chapter
``The \CLOS\ Meta-Object Protocol.''

\endsubSection%{Metaclasses}

\beginsubSection{Standard Metaclasses}

The \CLOS\ provides a number of predefined metaclasses.  These include the
classes {\bf standard-class}, {\bf built-in-class}, and {\bf
structure-class}:

\beginlist

\item{\bull}
The class {\bf standard-class} is the default class of classes defined
by {\bf defclass}.

\item{\bull} The class {\bf built-in-class} is the class whose
instances are classes that have special implementations with
restricted capabilities.  Any class that corresponds to a standard
Common Lisp type specified in {\it Common Lisp: The Language\/}
might be an instance of {\bf built-in-class}.
The predefined Common Lisp type specifiers that are required to have
corresponding classes are listed in Figure~1-1.  It is implementation
dependent whether each of these classes is implemented as a built-in class.

\item{\bull}
All classes defined by means of {\bf defstruct} are instances of 
{\bf structure-class}.
\endlist

\endsubSection%{Standard Metaclasses}

\beginsubSection{Standard Meta-objects}

The \OS\ supplies a set of meta-objects, called {\bit standard
meta-objects}. These include the class {\bf standard-object} and
instances of the classes {\bf standard-method}, {\bf
standard-generic-function}, and {\bf method-combination}.

\beginlist

\item{\bull} 
The class {\bf standard-method} is the default class of
methods defined by the forms {\bf defmethod}, {\bf
defgeneric}, {\bf generic-function}, {\bf generic-flet}, {\bf
generic-labels}, and {\bf with-added-methods}.

\item{\bull}
The class {\bf standard-generic-function} is the default class of 
generic functions defined by the forms {\bf defmethod},
{\bf defgeneric}, {\bf generic-function}, {\bf generic-flet},
{\bf generic-labels}, {\bf with-added-methods}, and {\bf defclass}.

\item{\bull} The class named {\bf standard-object} is an instance of
the class {\bf standard-class} and is a superclass of every class that
is an instance of {\bf standard-class} except itself and {\bf
structure-class}.

\item{\bull} Every method combination object is an instance of a
subclass of the class {\bf method-combination}.

\endlist

\endsubSection%{Standard Meta-objects} 

\endSection%{Meta-Objects}

\beginSection{Object Creation and Initialization}

The generic function {\bf make-instance} creates and returns a new
instance of a class.  The first argument is a class or the name of a
class, and the remaining arguments form an {\bit initialization argument\/}
list.  

The initialization of a new instance consists of several distinct
steps, including the following: combining the explicitly supplied
initialization arguments with default values for the unsupplied
initialization arguments, checking the validity of the initialization
arguments, allocating storage for the instance, filling slots with
values, and executing user-supplied methods that perform additional
initialization.  Each step of {\bf make-instance} is implemented by a
generic function to provide a mechanism for customizing that step.  In
addition, {\bf make-instance} is itself a generic function and thus
also can be customized.

The \OS\ specifies system-supplied primary methods for each step and
thus specifies a well-defined standard behavior for the entire
initialization process.  The standard behavior provides four simple
mechanisms for controlling initialization:

\beginlist

\item{\bull} Declaring a symbol to be an initialization argument for a
slot.  An initialization argument is declared by using the {\bf
:initarg} slot option to {\bf defclass}.  This provides a mechanism
for supplying a value for a slot in a call to {\bf make-instance}.

\item{\bull} Supplying a default value form for an initialization
argument.  Default value forms for initialization arguments are
defined by using the {\bf :default-initargs} class option to {\bf
defclass}.  If an initialization argument is not explicitly provided
as an argument to {\bf make-instance}, the default value form is
evaluated in the lexical environment of the {\bf defclass} form that
defined it, and the resulting value is used as the value of the
initialization argument.

\item{\bull} Supplying a default initial value form for a slot.  A
default initial value form for a slot is defined by using the {\bf
:initform} slot option to {\bf defclass}.  If no initialization
argument associated with that slot is given as an argument to {\bf
make-instance} or is defaulted by {\bf :default-initargs}, this
default initial value form is evaluated in the lexical environment of
the {\bf defclass} form that defined it, and the resulting value is
stored in the slot.  The {\bf :initform} form for a local slot may be
used when creating an instance, when updating an instance to conform
to a redefined class, or when updating an instance to conform to the
definition of a different class. The {\bf :initform} form for a shared
slot may be used when defining or re-defining the class.

\item{\bull} Defining methods for {\bf initialize-instance} and {\bf
shared-initialize}.  The slot-filling behavior described above is
implemented by a system-supplied primary method for {\bf
initialize-instance} which invokes {\bf shared-initialize}. The
generic function {\bf shared-initialize} implements the parts of
initialization shared by these four situations: when making an
instance, when re-initializing an instance, when updating an instance
to conform to a redefined class, and when updating an instance to
conform to the definition of a different class. The system-supplied
primary method for {\bf shared-initialize} directly implements the
slot-filling behavior described above, and {\bf initialize-instance}
simply invokes {\bf shared-initialize}.

\endlist

\beginsubSection{Initialization Arguments}

An initialization argument controls object creation and
initialization.  It is often convenient to use keyword symbols to name
initialization arguments, but the name of an initialization argument
can be any symbol, including {\bf nil}.  An initialization argument
can be used in two ways: to fill a slot with a value or to provide an
argument for an initialization method.  A single initialization
argument can be used for both purposes.

An {\bit initialization argument list\/} is a list of alternating
initialization argument names and values.  Its structure is identical
to a property list and also to the portion of an argument list
processed for {\bf \&key} parameters.  As in those lists, if an
initialization argument name appears more than once in an
initialization argument list, the leftmost occurrence supplies the
value and the remaining occurrences are ignored.  The arguments to
{\bf make-instance} (after the first argument) form an initialization
argument list.  Error-checking of initialization argument names is
disabled if the keyword argument pair whose keyword is {\bf
:allow-other-keys} and whose value is non-{\bf nil} appears in the
initialization argument list.

An initialization argument can be associated with a slot.  If the
initialization argument has a value in the initialization argument
list, the value is stored into the slot of the newly created object,
overriding any {\bf :initform} form associated with the slot.  A
single initialization argument can initialize more than one slot.  An
initialization argument that initializes a shared slot stores its
value into the shared slot, replacing any previous value.

An initialization argument can be associated with a method.  When an
object is created and a particular initialization argument is
supplied, the generic functions {\bf initialize-instance}, {\bf
shared-initialize}, and {\bf allocate-instance} are called with that
initialization argument's name and value as a keyword argument pair.
If a value for the initialization argument is not supplied in the
initialization argument list, the method's lambda-list supplies a
default value.

%End Part 4 of 6 concep.tex